#include "UdpServer.h"
#include <unp.h>

#define BUF_SIZE 4096

using namespace muduo;
using namespace muduo::net;

void sig_chld(int signo)
{
    pid_t pid;
    int stat;

    while ( (pid = waitpid(-1, &stat, WNOHANG)) > 0)
        printf("child %d terminated\n", pid);

    return;
}

UdpServer::UdpServer(const std::string &ip, int port)
    : hostIp_(ip),
      port_(port)
{

}

void UdpServer::setRecvCallback(const MessageCallback &cb)
{ msgCb_ = cb; }

void UdpServer::startListen()
{
    const int on = 1;
    struct sockaddr_in servaddr;

    // create udp sock
    udpFd_ = Socket(AF_INET, SOCK_DGRAM, 0);

    bzero(&servaddr, sizeof (servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    //servaddr.sin_addr.s_addr = inet_addr("10.10.17.51");
    servaddr.sin_port = htons(port_);

    Bind(udpFd_, (SA *)&servaddr, sizeof (servaddr));
    Signal(SIGCHLD, sig_chld);

    int maxFd;
    fd_set rset;
    int nready, ret, n;
    socklen_t len;
    maxFd = max(listenFd_, udpFd_) + 1;
    char mesg[BUF_SIZE];
    memset(mesg, 0, sizeof(mesg));

    // not select
    for ( ; ; )
    {
        len = sizeof (cliaddr_);
        n = Recvfrom(udpFd_, mesg, MAXLINE, 0, &cliaddr_, &len);

        // Sendto(sockfd, mesg, n, 0, pcliaddr, len);
//        printf("\nn:%d, len: %d\n", n, len);
//        printf("prepare recvBuf:%d\n",recvBuf_.readableBytes());
        recvBuf_.append(static_cast<char*>(mesg), n);
//        printf("after recvBuf:%d\n",recvBuf_.readableBytes());
        if(msgCb_)
            msgCb_(*this, &recvBuf_, Timestamp::now());
    }
//    return;
}
